home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
midi
/
justplay.lha
/
JustPlay
/
src
/
JustPlay.s
< prev
Wrap
Text File
|
1995-07-07
|
39KB
|
2,034 lines
**
** JustPlay 1.1
**
** $VER: justplay.s (08.07.95)
**
** written by Grzegorz Calkowski
**
** (C) Copyright 1995 The Beet Research
**
;==============================================================================
incdir "asminc:"
include "exec/exec.i"
include "dos/dos.i"
include "dos/dosextens.i"
include "devices/audio.i"
include "workbench/workbench.i"
include "workbench/startup.i"
include "libraries/xpk.i"
include "lvo30/exec_lib.i"
include "lvo30/dos_lib.i"
include "lvo30/intuition_lib.i"
include "lvo30/icon_lib.i"
include "lvo30/wb_lib.i"
include "gcmacros.i"
;==============================================================================
VeryBegin bra Begin
dc.b "$VER: JustPlay 1.1 by TBR (08.07.95)",0
even
;==============================================================================
Begin movem.l d0-a6,-(sp)
setexec
cmp #36,LIB_VERSION(a6)
bhi.s .kickok
st KickFlag
.kickok cla a1
call FindTask ; get our task
move.l d0,a4
tst.l pr_CLI(a4) ; start from cli?
bne.s .itscli
sf CLIFlag
lea pr_MsgPort(a4),a0 ; get the port
call WaitPort
lea pr_MsgPort(a4),a0
call GetMsg
move.l d0,WBMsg ; store the message
.itscli tst.b KickFlag
bne TooOldKick
;==============================================================================
setexec
lea RENDEZNAME(pc),a1
call FindPort
tst.l d0
beq.s .norendez
move.l d0,a0
move.l MP_SIGTASK(a0),a1
move.l #SIGBREAKF_CTRL_C,d0
call Signal
st QuietFlag
.norendez openlib DOSName
move.l d0,_DOSBase
beq Exit
openlib IntName
move.l d0,_IntuitionBase
beq CloseLibs
openlib IconName
move.l d0,_IconBase
beq CloseLibs
openlib WBName
move.l d0,_WBBase
beq CloseLibs
;==============================================================================
moveq #DOS_FIB,d1
cld d2
call AllocDosObject,DOS
move.l d0,FIB
beq CloseLibs
call CreateMsgPort ; create 'rendezvous' port
move.l d0,RendezPort
beq CleanUp
move.l d0,a1
lea RENDEZNAME(pc),a2
move.l a2,LN_NAME(a1)
move.b #5,LN_PRI(a1)
call AddPort ; make it public
call CreateMsgPort ; create msgport for audio
move.l d0,AudioPort
beq CleanUp
move.l d0,a0
move.l #ioa_SIZEOF,d0 ; size of AudioIO
call CreateIORequest
move.l d0,IORequest
beq CleanUp
move.l d0,a1
move.l #Channels,ioa_Data(a1)
move.l #1,ioa_Length(a1)
move #0,ioa_AllocKey(a1)
move.b #127,LN_PRI(a1)
lea AudioDevName(pc),a0
cld d0
cld d1
call OpenDevice
tst.l d0
beq.s .audiookay
cla a0
cla a2
cla a3
lea CantOpenAd_es(pc),a1
cmp.l #ADIOERR_ALLOCFAILED,d0
bne.s .cantopenatall
lea ChAlloc_es(pc),a1
.cantopenatall call EasyRequestArgs,Intuition
cmp.l #1,d0
beq.s .audiookay
bra CleanUp
.audiookay bsr setciaint
tst.l ciaabase
bne.s .ciaokay
cla a0
cla a2
cla a3
lea NoInt_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
;==============================================================================
.ciaokay setbase DOS
move.l WBMsg(pc),d0
bne.s .itwaswb
*************
* CLI
*************
lea TEMPLATE(pc),a0
move.l a0,d1
lea TmpVal(pc),a0
move.l a0,d2
cld d3
call ReadArgs
move.l d0,RDArgs
bne.s .argsokay
tst.b QuietFlag ; *QUIET*
bne CleanUp
call IoErr
move.l d0,d1
lea JustPlay_prompt(pc),a0
move.l a0,d2
call PrintFault
bra CleanUp
.argsokay lea TmpVal(pc),a2
move.l 4(a2),d0
beq.s .nodmawait_1
move.l d0,a0
move 2(a0),mt_dmadelay
.nodmawait_1 move.l (a2),d1
move.l d1,FName
move.l #ACCESS_READ,d2
call Lock
move.l d0,FLock
bne.w .locked
bsr CantRead
bra CleanUp
*************
* WB
*************
.itwaswb move.l d0,a2
cmp.l #2,sm_NumArgs(a2)
beq.s .gotarg
bhi.s .noextsel
tst.b QuietFlag
bne CleanUp ;*QUIET*
cla a0
cla a2
cla a3
lea NoArg_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
.noextsel move.l a2,-(sp)
cla a0
cla a2
cla a3
lea NoExtSel_es(pc),a1
call EasyRequestArgs,Intuition
move.l (sp)+,a2
.gotarg move.l sm_ArgList(a2),a2
move.l wa_Lock(a2),d1
call CurrentDir
move.l wa_Name(a2),a0
setbase Icon
call GetDiskObject
move.l d0,DiskObj
bne.s .goticon
cla a0
cla a2
cla a3
lea NoIcon_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
.goticon move.l d0,a0
move.l do_ToolTypes(a0),a0
move.l a0,a5
lea DMAWAIT_tt(pc),a1
call FindToolType
tst.l d0
beq.s .nodmawait
move.l d0,d1
move.l #TmpVal,d2
call StrToLong,DOS
tst.l d0
bmi.s .nodmawait
tst.l TmpVal
beq.s .nodmawait
move TmpVal+2(pc),mt_dmadelay
.nodmawait move.l a5,a0
lea ICONTEXT_tt(pc),a1
call FindToolType
tst.l d0
beq.s .noicontext
move.l d0,IconText
.noicontext move.l a5,a0
lea ICONXPOS_tt(pc),a1
call FindToolType
tst.l d0
beq.s .noxpos
move.l d0,d1
move.l #TmpVal,d2
call StrToLong,DOS
tst.l d0
bmi.s .noxpos
tst.l TmpVal
beq.s .noxpos
move.l TmpVal(pc),IconXPos
.noxpos move.l a5,a0
lea ICONYPOS_tt(pc),a1
call FindToolType
tst.l d0
beq.s .getarg
move.l d0,d1
move.l #TmpVal,d2
call StrToLong,DOS
tst.l d0
bmi.s .getarg
tst.l TmpVal
beq.s .getarg
move.l TmpVal(pc),IconYPos
.getarg setbase DOS
addq.l #8,a2
move.l wa_Lock(a2),d1
call CurrentDir
move.l wa_Name(a2),d1
move.l d1,FName
move.l #ACCESS_READ,d2
call Lock
move.l d0,FLock
bne.s .locked
bsr CantRead
bra CleanUp
************
.locked move.l d0,d1
move.l FIB(pc),d2
move.l d2,a2
call Examine
move.l d0,d7 ;save d0
move.l FLock(pc),d1
call UnLock
tst.l d7
bne.s .examok
bsr CantRead
bra CleanUp
.examok move.l fib_Size(a2),d0
addq.l #4,d0 ; if not - causes Mungwall hit
move.l d0,FileSize
moveq #MEMF_CHIP,d1
sys AllocMem
move.l d0,FileBuf
bne.s .memok
cla a0
cla a2
cla a3
lea NoMem_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
.memok move.l FName(pc),d1
move.l #MODE_OLDFILE,d2
call Open
move.l d0,FHandle
bne.s .opened
bsr CantRead
bra CleanUp
.opened move.l d0,d1
move.l FileBuf(pc),d2
move.l #512*3,d3
call Read
tst.l d0
bpl.s .read1ok
bsr CantRead
move.l FHandle(pc),d1
call Close
bra CleanUp
.read1ok move.l FileBuf(pc),a0
cmp.l #'XPKF',(a0)
beq.s .xpacked
cmp.l #'PP20',(a0) ; Decrunch PP (v1.1)
beq.s .xpacked
cmp.l #'M.K.',1080(a0)
beq.w .itismod
cmp.l #'FLT4',1080(a0)
beq.w .itismod
cla a0
cla a2
cla a3
lea NoMod_es(pc),a1
call EasyRequestArgs,Intuition
tst.l d0
bne.w .itismod
move.l FHandle(pc),d1
call Close
bra .freeit
;==============================================================================
.xpacked move.l FHandle(pc),d1
call Close
move.l FileBuf(pc),a1
move.l FileSize(pc),d0
setexec
call FreeMem
openlib XPKName
tst.l d0
beq.s .noxpk
move.l d0,a6
lea XPK_tags(pc),a0
move.l FName(pc),ti_Data(a0)
call XpkUnpack
move.l d0,d7
move.l a6,a1
setexec
call CloseLibrary
tst.l d7
beq .soplay
cla a0
cla a2
cla a3
lea XPKerr_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
.noxpk cla a0
cla a2
cla a3
lea NoXPK_es(pc),a1
call EasyRequestArgs,Intuition
bra CleanUp
;==============================================================================
.itismod move.l FHandle(pc),d1
move.l FileBuf(pc),d2
add.l #512*3,d2
move.l FileSize(pc),d3
sub.l #512*3,d3
call Read
move.l d0,d7
move.l FHandle(pc),d1
call Close
tst.l d7
bpl.s .soplay
bsr CantRead
bra CleanUp
;==============================================================================
.soplay tst.b CLIFlag
bne .noappicon
sys CreateMsgPort
move.l d0,AppIconPort
beq .noappicon
move.l d0,a1
move.l IconText(pc),a0
move.l DiskObj(pc),a3
move.l IconXPos(pc),do_CurrentX(a3)
move.l IconYPos(pc),do_CurrentY(a3)
cld d0
cld d1
cla a2
cla a4
call AddAppIconA,WB
move.l d0,AppIconPtr
beq.w .noappicon
bsr mt_init
st mt_enable
setexec
cld d7 ; will be "exit flag"
move.l AppIconPort(pc),a0
moveq #1,d0
cld d1
move.b MP_SIGBIT(a0),d1
lsl.l d1,d0 ; AppIconPort signal bit
move.l d0,AppIconPortF
move.b d1,AppIconPortB
.waitloop tst.b d7
bne.s .stopit
move.l AppIconPortF(pc),d0
or.l #SIGBREAKF_CTRL_C,d0
call Wait
btst #SIGBREAKB_CTRL_C,d0
bne.s .flushmsgs
cld d1
move.b AppIconPortB(pc),d1
btst d1,d0
beq.s .waitloop ; 0 means no AppIconPort
.nextmsg move.l AppIconPort(pc),a0
call GetMsg
tst.l d0
beq.s .waitloop
move.l d0,a1
cmp #MTYPE_APPICON,am_Type(a1)
bne.s .reply
tst.l am_NumArgs(a1)
bne.s .getlost
st d7
bra.s .reply
.getlost move.l a1,d6
cla a0
cla a2
cla a3
lea GetLost_es(pc),a1
call EasyRequestArgs,Intuition
move.l d6,a1
.reply call ReplyMsg
bra.s .nextmsg
.flushmsgs move.l AppIconPort(pc),a0
call GetMsg
tst.l d0
beq.s .stopit
move.l d0,a1
call ReplyMsg
bra.s .flushmsgs
.stopit move.l AppIconPtr(pc),a0
setbase WB
call RemoveAppIcon
move.l AppIconPort(pc),a0
setexec
call DeleteMsgPort
bsr mt_end
bra.s .freeit
;==============================================================================
.noappicon bsr mt_init
st mt_enable
setexec
move.l #SIGBREAKF_CTRL_C,d0
call Wait
bsr mt_end
;==============================================================================
.freeit setexec
move.l FileBuf(pc),a1
move.l FileSize(pc),d0
call FreeMem
;==============================================================================
CleanUp tst.l ciaabase
beq.s .noint
bsr resetciaint
.noint move.l DiskObj(pc),d0
beq.s .nodiskobj
setbase Icon
move.l d0,a0
call FreeDiskObject
.nodiskobj setexec
move.l IORequest(pc),d0
beq.s .nodev
move.l d0,a1
call CloseDevice
.nodev move.l IORequest(pc),d0
beq.s .noioreq
move.l d0,a0
call DeleteIORequest
.noioreq move.l RendezPort(pc),d7
beq.s .norendezport
move.l d7,a1
call RemPort
move.l d7,a0
call DeleteMsgPort
.norendezport move.l AudioPort(pc),d0
beq.s .noaudioport
move.l d0,a0
call DeleteMsgPort
.noaudioport setbase DOS ;DOS now
move.l FIB(pc),d2
beq.s .nofib
moveq #DOS_FIB,d1
call FreeDosObject
.nofib
move.l RDArgs(pc),d1
beq.s .nordargs
call FreeArgs
.nordargs
CloseLibs setexec
clslib DOS
clslib Intuition
clslib Icon
clslib WB
;==============================================================================
Exit move.l WBMsg(pc),d0
beq.s .nowb
move.l d0,a1
setexec
call Forbid ; NOTE! NO Permit needed!
call ReplyMsg
.nowb movem.l (sp)+,d0-a6
moveq #0,d0
rts
;==============================================================================
TooOldKick openlib DOSName
move.l d0,a6
tst.l d0
beq Exit ; no dos...
move.l d0,a6
move.l #.outwindow,d1 ; we wanna window
move.l #MODE_NEWFILE,d2
call Open
tst.l d0 ; couldn't open?
beq.s .clsdos
move.l d0,d7 ; store handle in d7
move.l d7,d1
move.l #.kicktxt,d2 ; text to display
move.l #.keybuf-.kicktxt,d3
call Write
move.l d7,d1
move.l #.keybuf,d2
moveq #1,d3
call Read ; read any key
move.l d7,d1
call Close
.clsdos move.l a6,a1
setexec
call CloseLibrary
bra Exit
.outwindow dc.b "RAW:40/40/350/60/JustPlay v1.1",0
.kicktxt dc.b 10,"Required at least Kickstart V37.",10,10
dc.b "Press any key to continue... "
.keybuf dc.b 0
even
;==============================================================================
CantRead cla a0
cla a2
cla a3
lea CantRead_es(pc),a1
call EasyRequestArgs,Intuition
rts
;==============================================================================
_DOSBase dc.l 0
_IntuitionBase dc.l 0
_IconBase dc.l 0
_WBBase dc.l 0
WBMsg dc.l 0
AudioPort dc.l 0
IORequest dc.l 0
FName dc.l 0
FHandle dc.l 0
FLock dc.l 0
FIB dc.l 0
DiskObj dc.l 0
AppIconPtr dc.l 0
AppIconPort dc.l 0
AppIconPortF dc.l 0
RDArgs dc.l 0
RendezPort dc.l 0
FileSize dc.l 0
FileBuf dc.l 0
IconText dc.l Stop_txt
IconXPos dc.l NO_ICON_POSITION
IconYPos dc.l NO_ICON_POSITION
TmpVal dc.l 0,0
XPK_tags dc.l XPK_InName,0
dc.l XPK_GetOutBuf,FileBuf
dc.l XPK_GetOutBufLen,FileSize
dc.l XPK_GetOutLen,TmpVal
dc.l XPK_OutMemType,MEMF_CHIP
dc.l TAG_DONE
AppIconPortB dc.b 0
Channels dc.b %1111
CLIFlag dc.b 1
KickFlag dc.b 0
QuietFlag dc.b 0
XPKFlag dc.b 0
DOSName dc.b "dos.library",0
IntName dc.b "intuition.library",0
IconName dc.b "icon.library",0
WBName dc.b "workbench.library",0
XPKName dc.b "xpkmaster.library",0
AudioDevName dc.b "audio.device",0
even
;==============================================================================
GetLost_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "JustPlay v1.1",10
dc.b "by Grzegorz Calkowski",10
dc.b "© 1995 The Beet Research",0
.gads dc.b "Nice to know",0
NoIcon_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Can't get icon! Failed...",0
.gads dc.b "I'll fix it",0
ChAlloc_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Can't allocate audio channels!",0
.gads dc.b "Don't care|Cancel",0,0
CantOpenAd_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Can't open audio.device!",0
.gads dc.b "Pity",0
NoArg_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "No module given.",0
.gads dc.b "Sure",0
NoExtSel_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "No extended select allowed:",10
dc.b "Only first module will be played.",0
.gads dc.b "I see",0
NoMod_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "The file is NOT an ordinary module.",10
dc.b "Only NT/PT/STR-modules supported.",0
.gads dc.b "Play anyway|Cancel",0,0
NoInt_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "No CIA interrupt available.",0
.gads dc.b "Hmmm",0,0
NoMem_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Insufficient memory.",0
.gads dc.b "Hard to hear",0
CantRead_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Can't read the file!",0
.gads dc.b "Bye",0,0
NoXPK_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "No xpkmaster.library found.",10
dc.b "File can't be decrunched.",0
.gads dc.b "I see",0
XPKerr_es dc.l EasyStruct_SIZEOF,0
dc.l JustPlay_txt,.text,.gads
.text dc.b "Can't read/decrunch the file!",0
.gads dc.b "Bye",0
;==============================================================================
TEMPLATE dc.b "MODULE/A,DMAWAIT/K/N",0
DMAWAIT_tt dc.b "DMAWAIT",0
ICONTEXT_tt dc.b "ICONTEXT",0
ICONXPOS_tt dc.b "ICONXPOS",0
ICONYPOS_tt dc.b "ICONYPOS",0
RENDEZNAME dc.b "JustPlay.rendezvous",0
;==============================================================================
JustPlay_prompt dc.b "JustPlay",0
JustPlay_txt dc.b "JustPlay v1.1",0
Stop_txt dc.b "STOP!",0
KickOld_msg dc.b "Required at least Kickstart V37.",10,0
KickOld_msg_len equ *-KickOld_msg
cnop 0,4
;==============================================================================
;**************************************************
;* ----- Protracker V2.1A Playroutine ----- *
;* Peter "CRAYON" Hanning / Mushroom Studios 1992 *
;* Vinterstigen 12, 14440 Ronninge, Sweden *
;**************************************************
;---- cia interrupt ----
addicrvector = -6
remicrvector = -12
lvoopenresource = -498
lvoopenlibrary = -552
lvocloselibrary = -414
lvodelay = -198
ciatalo = $400
ciatahi = $500
ciatblo = $600
ciatbhi = $700
ciacra = $e00
ciacrb = $f00
setciaint
moveq #2,d6
lea $bfd000,a5
move.b #'b',ciaaname+3
setcialoop
moveq #0,d0
lea ciaaname(pc),a1
move.l 4.w,a6
jsr lvoopenresource(a6)
move.l d0,ciaabase
beq mt_return
lea gfxname(pc),a1
moveq #0,d0
jsr lvoopenlibrary(a6)
tst.l d0
beq resetciaint
move.l d0,a1
move.w 206(a1),d0 ; displayflags
btst #2,d0 ; pal?
beq.s wasntsc
move.l #1773447,d7 ; pal
bra.s sciask
wasntsc move.l #1789773,d7 ; ntsc
sciask move.l d7,timervalue
divu #125,d7 ; default to normal 50 hz timer
jsr lvocloselibrary(a6)
move.l ciaabase(pc),a6
cmp.w #2,d6
beq.s trytimera
trytimerb
lea musicintserver(pc),a1
moveq #1,d0 ; bit 1: timer b
jsr addicrvector(a6)
move.l #1,timerflag
tst.l d0
bne.s ciaerror
move.l a5,ciaaaddr
move.b d7,ciatblo(a5)
lsr.w #8,d7
move.b d7,ciatbhi(a5)
bset #0,ciacrb(a5)
rts
trytimera
lea musicintserver(pc),a1
moveq #0,d0 ; bit 0: timer a
jsr addicrvector(a6)
clr.l timerflag
tst.l d0
bne.s ciaerror
move.l a5,ciaaaddr
move.b d7,ciatalo(a5)
lsr.w #8,d7
move.b d7,ciatahi(a5)
bset #0,ciacra(a5)
rts
ciaerror
move.b #'a',ciaaname+3
lea $bfe001,a5
subq.w #1,d6
bne setcialoop
clr.l ciaabase
rts
resetciaint
move.l ciaabase(pc),d0
beq mt_return
clr.l ciaabase
move.l d0,a6
move.l ciaaaddr(pc),a5
tst.l timerflag
beq.s restimera
bclr #0,ciacrb(a5)
moveq #1,d0
bra.s remint
restimera
bclr #0,ciacra(a5)
moveq #0,d0
remint lea musicintserver(pc),a1
moveq #0,d0
jsr remicrvector(a6)
rts
;---- tempo ----
settempo
move.l ciaabase(pc),d2
beq mt_return
cmp.w #32,d0
bhs.s setemsk
moveq #32,d0
setemsk move.w d0,realtempo
move.l timervalue(pc),d2
divu d0,d2
move.l ciaaaddr(pc),a4
move.l timerflag(pc),d0
beq.s settema
move.b d2,ciatblo(a4)
lsr.w #8,d2
move.b d2,ciatbhi(a4)
rts
settema move.b d2,ciatalo(a4)
lsr.w #8,d2
move.b d2,ciatahi(a4)
rts
realtempo dc.w 125
ciaaaddr dc.l 0
ciaaname dc.b "ciaa.resource",0
ciaabase dc.l 0
timerflag dc.l 0
timervalue dc.l 0
gfxname dc.b "graphics.library",0,0
musicintserver
dc.l 0,0
dc.b 2,5 ; type, priority
dc.l musintname
dc.l 0,mt_music
musintname dc.b "protracker musicint",0
;---- playroutine ----
n_note equ 0 ; w
n_cmd equ 2 ; w
n_cmdlo equ 3 ; b
n_start equ 4 ; l
n_length equ 8 ; w
n_loopstart equ 10 ; l
n_replen equ 14 ; w
n_period equ 16 ; w
n_finetune equ 18 ; b
n_volume equ 19 ; b
n_dmabit equ 20 ; w
n_toneportdirec equ 22 ; b
n_toneportspeed equ 23 ; b
n_wantedperiod equ 24 ; w
n_vibratocmd equ 26 ; b
n_vibratopos equ 27 ; b
n_tremolocmd equ 28 ; b
n_tremolopos equ 29 ; b
n_wavecontrol equ 30 ; b
n_glissfunk equ 31 ; b
n_sampleoffset equ 32 ; b
n_pattpos equ 33 ; b
n_loopcount equ 34 ; b
n_funkoffset equ 35 ; b
n_wavestart equ 36 ; l
n_reallength equ 40 ; w
mt_init move.l FileBuf(pc),a0
move.l a0,mt_songdataptr
move.l a0,a1
lea 952(a1),a1
moveq #127,d0
moveq #0,d1
mtloop move.l d1,d2
subq.w #1,d0
mtloop2 move.b (a1)+,d1
cmp.b d2,d1
bgt.s mtloop
dbra d0,mtloop2
addq.b #1,d2
lea mt_samplestarts(pc),a1
asl.l #8,d2
asl.l #2,d2
add.l #1084,d2
add.l a0,d2
move.l d2,a2
moveq #30,d0
mtloop3 clr.l (a2)
move.l a2,(a1)+
moveq #0,d1
move.w 42(a0),d1
asl.l #1,d1
add.l d1,a2
add.l #30,a0
dbra d0,mtloop3
or.b #2,$bfe001
move.b #6,mt_speed
clr.b mt_counter
clr.b mt_songpos
clr.w mt_patternpos
mt_end sf mt_enable
lea $dff000,a0
clr.w $a8(a0)
clr.w $b8(a0)
clr.w $c8(a0)
clr.w $d8(a0)
move.w #$f,$dff096
rts
mt_music
movem.l d0-d4/a0-a6,-(sp)
tst.b mt_enable
beq mt_exit
addq.b #1,mt_counter
move.b mt_counter(pc),d0
cmp.b mt_speed(pc),d0
blo.s mt_nonewnote
clr.b mt_counter
tst.b mt_pattdeltime2
beq.s mt_getnewnote
bsr.s mt_nonewallchannels
bra mt_dskip
mt_nonewnote
bsr.s mt_nonewallchannels
bra mt_nonewposyet
mt_nonewallchannels
lea $dff0a0,a5
lea mt_chan1temp(pc),a6
bsr mt_checkefx
lea $dff0b0,a5
lea mt_chan2temp(pc),a6
bsr mt_checkefx
lea $dff0c0,a5
lea mt_chan3temp(pc),a6
bsr mt_checkefx
lea $dff0d0,a5
lea mt_chan4temp(pc),a6
bra mt_checkefx
mt_getnewnote
move.l mt_songdataptr(pc),a0
lea 12(a0),a3
lea 952(a0),a2 ;pattpo
lea 1084(a0),a0 ;patterndata
moveq #0,d0
moveq #0,d1
move.b mt_songpos(pc),d0
move.b (a2,d0.w),d1
asl.l #8,d1
asl.l #2,d1
add.w mt_patternpos(pc),d1
clr.w mt_dmacontemp
lea $dff0a0,a5
lea mt_chan1temp(pc),a6
bsr.s mt_playvoice
lea $dff0b0,a5
lea mt_chan2temp(pc),a6
bsr.s mt_playvoice
lea $dff0c0,a5
lea mt_chan3temp(pc),a6
bsr.s mt_playvoice
lea $dff0d0,a5
lea mt_chan4temp(pc),a6
bsr.s mt_playvoice
bra mt_setdma
mt_playvoice
tst.l (a6)
bne.s mt_plvskip
bsr mt_pernop
mt_plvskip
move.l (a0,d1.l),(a6)
addq.l #4,d1
moveq #0,d2
move.b n_cmd(a6),d2
and.b #$f0,d2
lsr.b #4,d2
move.b (a6),d0
and.b #$f0,d0
or.b d0,d2
tst.b d2
beq mt_setregs
moveq #0,d3
lea mt_samplestarts(pc),a1
move d2,d4
subq.l #1,d2
asl.l #2,d2
mulu #30,d4
move.l (a1,d2.l),n_start(a6)
move.w (a3,d4.l),n_length(a6)
move.w (a3,d4.l),n_reallength(a6)
move.b 2(a3,d4.l),n_finetune(a6)
move.b 3(a3,d4.l),n_volume(a6)
move.w 4(a3,d4.l),d3 ; get repeat
tst.w d3
beq.s mt_noloop
move.l n_start(a6),d2 ; get start
asl.w #1,d3
add.l d3,d2 ; add repeat
move.l d2,n_loopstart(a6)
move.l d2,n_wavestart(a6)
move.w 4(a3,d4.l),d0 ; get repeat
add.w 6(a3,d4.l),d0 ; add replen
move.w d0,n_length(a6)
move.w 6(a3,d4.l),n_replen(a6) ; save replen
moveq #0,d0
move.b n_volume(a6),d0
move.w d0,8(a5) ; set volume
bra.s mt_setregs
mt_noloop
move.l n_start(a6),d2
add.l d3,d2
move.l d2,n_loopstart(a6)
move.l d2,n_wavestart(a6)
move.w 6(a3,d4.l),n_replen(a6) ; save replen
moveq #0,d0
move.b n_volume(a6),d0
move.w d0,8(a5) ; set volume
mt_setregs
move.w (a6),d0
and.w #$0fff,d0
beq mt_checkmoreefx ; if no note
move.w 2(a6),d0
and.w #$0ff0,d0
cmp.w #$0e50,d0
beq.s mt_dosetfinetune
move.b 2(a6),d0
and.b #$0f,d0
cmp.b #3,d0 ; toneportamento
beq.s mt_chktoneporta
cmp.b #5,d0
beq.s mt_chktoneporta
cmp.b #9,d0 ; sample offset
bne.s mt_setperiod
bsr mt_checkmoreefx
bra.s mt_setperiod
mt_dosetfinetune
bsr mt_setfinetune
bra.s mt_setperiod
mt_chktoneporta
bsr mt_settoneporta
bra mt_checkmoreefx
mt_setperiod
movem.l d0-d1/a0-a1,-(sp)
move.w (a6),d1
and.w #$0fff,d1
lea mt_periodtable(pc),a1
moveq #0,d0
moveq #36,d2
mt_ftuloop
cmp.w (a1,d0.w),d1
bhs.s mt_ftufound
addq.l #2,d0
dbra d2,mt_ftuloop
mt_ftufound
moveq #0,d1
move.b n_finetune(a6),d1
mulu #36*2,d1
add.l d1,a1
move.w (a1,d0.w),n_period(a6)
movem.l (sp)+,d0-d1/a0-a1
move.w 2(a6),d0
and.w #$0ff0,d0
cmp.w #$0ed0,d0 ; notedelay
beq mt_checkmoreefx
move.w n_dmabit(a6),$dff096
btst #2,n_wavecontrol(a6)
bne.s mt_vibnoc
clr.b n_vibratopos(a6)
mt_vibnoc
btst #6,n_wavecontrol(a6)
bne.s mt_trenoc
clr.b n_tremolopos(a6)
mt_trenoc
move.l n_start(a6),(a5) ; set start
move.w n_length(a6),4(a5) ; set length
move.w n_period(a6),d0
move.w d0,6(a5) ; set period
move.w n_dmabit(a6),d0
or.w d0,mt_dmacontemp
bra mt_checkmoreefx
mt_setdma
move mt_dmadelay(pc),d0
mt_waitdma
dbra d0,mt_waitdma
move.w mt_dmacontemp(pc),d0
or.w #$8000,d0
move.w d0,$dff096
move.w #300,d0
mt_waitdma2
dbra d0,mt_waitdma2
lea $dff000,a5
lea mt_chan4temp(pc),a6
move.l n_loopstart(a6),$d0(a5)
move.w n_replen(a6),$d4(a5)
lea mt_chan3temp(pc),a6
move.l n_loopstart(a6),$c0(a5)
move.w n_replen(a6),$c4(a5)
lea mt_chan2temp(pc),a6
move.l n_loopstart(a6),$b0(a5)
move.w n_replen(a6),$b4(a5)
lea mt_chan1temp(pc),a6
move.l n_loopstart(a6),$a0(a5)
move.w n_replen(a6),$a4(a5)
mt_dskip
add.w #16,mt_patternpos
move.b mt_pattdeltime,d0
beq.s mt_dskc
move.b d0,mt_pattdeltime2
clr.b mt_pattdeltime
mt_dskc tst.b mt_pattdeltime2
beq.s mt_dska
subq.b #1,mt_pattdeltime2
beq.s mt_dska
sub.w #16,mt_patternpos
mt_dska tst.b mt_pbreakflag
beq.s mt_nnpysk
sf mt_pbreakflag
moveq #0,d0
move.b mt_pbreakpos(pc),d0
clr.b mt_pbreakpos
lsl.w #4,d0
move.w d0,mt_patternpos
mt_nnpysk
cmp.w #1024,mt_patternpos
blo.s mt_nonewposyet
mt_nextposition
moveq #0,d0
move.b mt_pbreakpos(pc),d0
lsl.w #4,d0
move.w d0,mt_patternpos
clr.b mt_pbreakpos
clr.b mt_posjumpflag
addq.b #1,mt_songpos
and.b #$7f,mt_songpos
move.b mt_songpos(pc),d1
move.l mt_songdataptr(pc),a0
cmp.b 950(a0),d1
blo.s mt_nonewposyet
clr.b mt_songpos
mt_nonewposyet
tst.b mt_posjumpflag
bne.s mt_nextposition
mt_exit movem.l (sp)+,d0-d4/a0-a6
rts
mt_checkefx
bsr mt_updatefunk
move.w n_cmd(a6),d0
and.w #$0fff,d0
beq.s mt_pernop
move.b n_cmd(a6),d0
and.b #$0f,d0
beq.s mt_arpeggio
cmp.b #1,d0
beq mt_portaup
cmp.b #2,d0
beq mt_portadown
cmp.b #3,d0
beq mt_toneportamento
cmp.b #4,d0
beq mt_vibrato
cmp.b #5,d0
beq mt_toneplusvolslide
cmp.b #6,d0
beq mt_vibratoplusvolslide
cmp.b #$e,d0
beq mt_e_commands
setback move.w n_period(a6),6(a5)
cmp.b #7,d0
beq mt_tremolo
cmp.b #$a,d0
beq mt_volumeslide
mt_return
rts
mt_pernop
move.w n_period(a6),6(a5)
rts
mt_arpeggio
moveq #0,d0
move.b mt_counter(pc),d0
divs #3,d0
swap d0
cmp.w #0,d0
beq.s mt_arpeggio2
cmp.w #2,d0
beq.s mt_arpeggio1
moveq #0,d0
move.b n_cmdlo(a6),d0
lsr.b #4,d0
bra.s mt_arpeggio3
mt_arpeggio1
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #15,d0
bra.s mt_arpeggio3
mt_arpeggio2
move.w n_period(a6),d2
bra.s mt_arpeggio4
mt_arpeggio3
asl.w #1,d0
moveq #0,d1
move.b n_finetune(a6),d1
mulu #36*2,d1
lea mt_periodtable(pc),a0
add.l d1,a0
moveq #0,d1
move.w n_period(a6),d1
moveq #36,d3
mt_arploop
move.w (a0,d0.w),d2
cmp.w (a0),d1
bhs.s mt_arpeggio4
addq.l #2,a0
dbra d3,mt_arploop
rts
mt_arpeggio4
move.w d2,6(a5)
rts
mt_fineportaup
tst.b mt_counter
bne.s mt_return
move.b #$0f,mt_lowmask
mt_portaup
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b mt_lowmask(pc),d0
move.b #$ff,mt_lowmask
sub.w d0,n_period(a6)
move.w n_period(a6),d0
and.w #$0fff,d0
cmp.w #113,d0
bpl.s mt_portauskip
and.w #$f000,n_period(a6)
or.w #113,n_period(a6)
mt_portauskip
move.w n_period(a6),d0
and.w #$0fff,d0
move.w d0,6(a5)
rts
mt_fineportadown
tst.b mt_counter
bne mt_return
move.b #$0f,mt_lowmask
mt_portadown
clr.w d0
move.b n_cmdlo(a6),d0
and.b mt_lowmask(pc),d0
move.b #$ff,mt_lowmask
add.w d0,n_period(a6)
move.w n_period(a6),d0
and.w #$0fff,d0
cmp.w #856,d0
bmi.s mt_portadskip
and.w #$f000,n_period(a6)
or.w #856,n_period(a6)
mt_portadskip
move.w n_period(a6),d0
and.w #$0fff,d0
move.w d0,6(a5)
rts
mt_settoneporta
move.l a0,-(sp)
move.w (a6),d2
and.w #$0fff,d2
moveq #0,d0
move.b n_finetune(a6),d0
mulu #37*2,d0
lea mt_periodtable(pc),a0
add.l d0,a0
moveq #0,d0
mt_stploop
cmp.w (a0,d0.w),d2
bhs.s mt_stpfound
addq.w #2,d0
cmp.w #37*2,d0
blo.s mt_stploop
moveq #35*2,d0
mt_stpfound
move.b n_finetune(a6),d2
and.b #8,d2
beq.s mt_stpgoss
tst.w d0
beq.s mt_stpgoss
subq.w #2,d0
mt_stpgoss
move.w (a0,d0.w),d2
move.l (sp)+,a0
move.w d2,n_wantedperiod(a6)
move.w n_period(a6),d0
clr.b n_toneportdirec(a6)
cmp.w d0,d2
beq.s mt_cleartoneporta
bge mt_return
move.b #1,n_toneportdirec(a6)
rts
mt_cleartoneporta
clr.w n_wantedperiod(a6)
rts
mt_toneportamento
move.b n_cmdlo(a6),d0
beq.s mt_toneportnochange
move.b d0,n_toneportspeed(a6)
clr.b n_cmdlo(a6)
mt_toneportnochange
tst.w n_wantedperiod(a6)
beq mt_return
moveq #0,d0
move.b n_toneportspeed(a6),d0
tst.b n_toneportdirec(a6)
bne.s mt_toneportaup
mt_toneportadown
add.w d0,n_period(a6)
move.w n_wantedperiod(a6),d0
cmp.w n_period(a6),d0
bgt.s mt_toneportasetper
move.w n_wantedperiod(a6),n_period(a6)
clr.w n_wantedperiod(a6)
bra.s mt_toneportasetper
mt_toneportaup
sub.w d0,n_period(a6)
move.w n_wantedperiod(a6),d0
cmp.w n_period(a6),d0
blt.s mt_toneportasetper
move.w n_wantedperiod(a6),n_period(a6)
clr.w n_wantedperiod(a6)
mt_toneportasetper
move.w n_period(a6),d2
move.b n_glissfunk(a6),d0
and.b #$0f,d0
beq.s mt_glissskip
moveq #0,d0
move.b n_finetune(a6),d0
mulu #36*2,d0
lea mt_periodtable(pc),a0
add.l d0,a0
moveq #0,d0
mt_glissloop
cmp.w (a0,d0.w),d2
bhs.s mt_glissfound
addq.w #2,d0
cmp.w #36*2,d0
blo.s mt_glissloop
moveq #35*2,d0
mt_glissfound
move.w (a0,d0.w),d2
mt_glissskip
move.w d2,6(a5) ; set period
rts
mt_vibrato
move.b n_cmdlo(a6),d0
beq.s mt_vibrato2
move.b n_vibratocmd(a6),d2
and.b #$0f,d0
beq.s mt_vibskip
and.b #$f0,d2
or.b d0,d2
mt_vibskip
move.b n_cmdlo(a6),d0
and.b #$f0,d0
beq.s mt_vibskip2
and.b #$0f,d2
or.b d0,d2
mt_vibskip2
move.b d2,n_vibratocmd(a6)
mt_vibrato2
move.b n_vibratopos(a6),d0
lea mt_vibratotable(pc),a4
lsr.w #2,d0
and.w #$001f,d0
moveq #0,d2
move.b n_wavecontrol(a6),d2
and.b #$03,d2
beq.s mt_vib_sine
lsl.b #3,d0
cmp.b #1,d2
beq.s mt_vib_rampdown
move.b #255,d2
bra.s mt_vib_set
mt_vib_rampdown
tst.b n_vibratopos(a6)
bpl.s mt_vib_rampdown2
move.b #255,d2
sub.b d0,d2
bra.s mt_vib_set
mt_vib_rampdown2
move.b d0,d2
bra.s mt_vib_set
mt_vib_sine
move.b (a4,d0.w),d2
mt_vib_set
move.b n_vibratocmd(a6),d0
and.w #15,d0
mulu d0,d2
lsr.w #7,d2
move.w n_period(a6),d0
tst.b n_vibratopos(a6)
bmi.s mt_vibratoneg
add.w d2,d0
bra.s mt_vibrato3
mt_vibratoneg
sub.w d2,d0
mt_vibrato3
move.w d0,6(a5)
move.b n_vibratocmd(a6),d0
lsr.w #2,d0
and.w #$003c,d0
add.b d0,n_vibratopos(a6)
rts
mt_toneplusvolslide
bsr mt_toneportnochange
bra mt_volumeslide
mt_vibratoplusvolslide
bsr.s mt_vibrato2
bra mt_volumeslide
mt_tremolo
move.b n_cmdlo(a6),d0
beq.s mt_tremolo2
move.b n_tremolocmd(a6),d2
and.b #$0f,d0
beq.s mt_treskip
and.b #$f0,d2
or.b d0,d2
mt_treskip
move.b n_cmdlo(a6),d0
and.b #$f0,d0
beq.s mt_treskip2
and.b #$0f,d2
or.b d0,d2
mt_treskip2
move.b d2,n_tremolocmd(a6)
mt_tremolo2
move.b n_tremolopos(a6),d0
lea mt_vibratotable(pc),a4
lsr.w #2,d0
and.w #$001f,d0
moveq #0,d2
move.b n_wavecontrol(a6),d2
lsr.b #4,d2
and.b #$03,d2
beq.s mt_tre_sine
lsl.b #3,d0
cmp.b #1,d2
beq.s mt_tre_rampdown
move.b #255,d2
bra.s mt_tre_set
mt_tre_rampdown
tst.b n_vibratopos(a6)
bpl.s mt_tre_rampdown2
move.b #255,d2
sub.b d0,d2
bra.s mt_tre_set
mt_tre_rampdown2
move.b d0,d2
bra.s mt_tre_set
mt_tre_sine
move.b (a4,d0.w),d2
mt_tre_set
move.b n_tremolocmd(a6),d0
and.w #15,d0
mulu d0,d2
lsr.w #6,d2
moveq #0,d0
move.b n_volume(a6),d0
tst.b n_tremolopos(a6)
bmi.s mt_tremoloneg
add.w d2,d0
bra.s mt_tremolo3
mt_tremoloneg
sub.w d2,d0
mt_tremolo3
bpl.s mt_tremoloskip
clr.w d0
mt_tremoloskip
cmp.w #$40,d0
bls.s mt_tremolook
move.w #$40,d0
mt_tremolook
move.w d0,8(a5)
move.b n_tremolocmd(a6),d0
lsr.w #2,d0
and.w #$003c,d0
add.b d0,n_tremolopos(a6)
rts
mt_sampleoffset
moveq #0,d0
move.b n_cmdlo(a6),d0
beq.s mt_sononew
move.b d0,n_sampleoffset(a6)
mt_sononew
move.b n_sampleoffset(a6),d0
lsl.w #7,d0
cmp.w n_length(a6),d0
bge.s mt_sofskip
sub.w d0,n_length(a6)
lsl.w #1,d0
add.l d0,n_start(a6)
rts
mt_sofskip
move.w #$0001,n_length(a6)
rts
mt_volumeslide
moveq #0,d0
move.b n_cmdlo(a6),d0
lsr.b #4,d0
tst.b d0
beq.s mt_volslidedown
mt_volslideup
add.b d0,n_volume(a6)
cmp.b #$40,n_volume(a6)
bmi.s mt_vsuskip
move.b #$40,n_volume(a6)
mt_vsuskip
move.b n_volume(a6),d0
move.w d0,8(a5)
rts
mt_volslidedown
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
mt_volslidedown2
sub.b d0,n_volume(a6)
bpl.s mt_vsdskip
clr.b n_volume(a6)
mt_vsdskip
move.b n_volume(a6),d0
move.w d0,8(a5)
rts
mt_positionjump
move.b n_cmdlo(a6),d0
subq.b #1,d0
move.b d0,mt_songpos
mt_pj2 clr.b mt_pbreakpos
st mt_posjumpflag
rts
mt_volumechange
moveq #0,d0
move.b n_cmdlo(a6),d0
cmp.b #$40,d0
bls.s mt_volumeok
moveq #$40,d0
mt_volumeok
move.b d0,n_volume(a6)
move.w d0,8(a5)
rts
mt_patternbreak
moveq #0,d0
move.b n_cmdlo(a6),d0
move.l d0,d2
lsr.b #4,d0
mulu #10,d0
and.b #$0f,d2
add.b d2,d0
cmp.b #63,d0
bhi.s mt_pj2
move.b d0,mt_pbreakpos
st mt_posjumpflag
rts
mt_setspeed
moveq #0,d0
move.b 3(a6),d0
beq mt_end
cmp.b #32,d0
bhs settempo
clr.b mt_counter
move.b d0,mt_speed
rts
mt_checkmoreefx
bsr mt_updatefunk
move.b 2(a6),d0
and.b #$0f,d0
cmp.b #$9,d0
beq mt_sampleoffset
cmp.b #$b,d0
beq mt_positionjump
cmp.b #$d,d0
beq.s mt_patternbreak
cmp.b #$e,d0
beq.s mt_e_commands
cmp.b #$f,d0
beq.s mt_setspeed
cmp.b #$c,d0
beq mt_volumechange
bra mt_pernop
mt_e_commands
move.b n_cmdlo(a6),d0
and.b #$f0,d0
lsr.b #4,d0
beq.s mt_filteronoff
cmp.b #1,d0
beq mt_fineportaup
cmp.b #2,d0
beq mt_fineportadown
cmp.b #3,d0
beq.s mt_setglisscontrol
cmp.b #4,d0
beq mt_setvibratocontrol
cmp.b #5,d0
beq mt_setfinetune
cmp.b #6,d0
beq mt_jumploop
cmp.b #7,d0
beq mt_settremolocontrol
cmp.b #9,d0
beq mt_retrignote
cmp.b #$a,d0
beq mt_volumefineup
cmp.b #$b,d0
beq mt_volumefinedown
cmp.b #$c,d0
beq mt_notecut
cmp.b #$d,d0
beq mt_notedelay
cmp.b #$e,d0
beq mt_patterndelay
cmp.b #$f,d0
beq mt_funkit
rts
mt_filteronoff
move.b n_cmdlo(a6),d0
and.b #1,d0
asl.b #1,d0
and.b #$fd,$bfe001
or.b d0,$bfe001
rts
mt_setglisscontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
and.b #$f0,n_glissfunk(a6)
or.b d0,n_glissfunk(a6)
rts
mt_setvibratocontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
and.b #$f0,n_wavecontrol(a6)
or.b d0,n_wavecontrol(a6)
rts
mt_setfinetune
move.b n_cmdlo(a6),d0
and.b #$0f,d0
move.b d0,n_finetune(a6)
rts
mt_jumploop
tst.b mt_counter
bne mt_return
move.b n_cmdlo(a6),d0
and.b #$0f,d0
beq.s mt_setloop
tst.b n_loopcount(a6)
beq.s mt_jumpcnt
subq.b #1,n_loopcount(a6)
beq mt_return
mt_jmploop move.b n_pattpos(a6),mt_pbreakpos
st mt_pbreakflag
rts
mt_jumpcnt
move.b d0,n_loopcount(a6)
bra.s mt_jmploop
mt_setloop
move.w mt_patternpos(pc),d0
lsr.w #4,d0
move.b d0,n_pattpos(a6)
rts
mt_settremolocontrol
move.b n_cmdlo(a6),d0
and.b #$0f,d0
lsl.b #4,d0
and.b #$0f,n_wavecontrol(a6)
or.b d0,n_wavecontrol(a6)
rts
mt_retrignote
move.l d1,-(sp)
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
beq.s mt_rtnend
moveq #0,d1
move.b mt_counter(pc),d1
bne.s mt_rtnskp
move.w (a6),d1
and.w #$0fff,d1
bne.s mt_rtnend
moveq #0,d1
move.b mt_counter(pc),d1
mt_rtnskp
divu d0,d1
swap d1
tst.w d1
bne.s mt_rtnend
mt_doretrig
move.w n_dmabit(a6),$dff096 ; channel dma off
move.l n_start(a6),(a5) ; set sampledata pointer
move.w n_length(a6),4(a5) ; set length
move.w #300,d0
mt_rtnloop1
dbra d0,mt_rtnloop1
move.w n_dmabit(a6),d0
bset #15,d0
move.w d0,$dff096
move.w #300,d0
mt_rtnloop2
dbra d0,mt_rtnloop2
move.l n_loopstart(a6),(a5)
move.l n_replen(a6),4(a5)
mt_rtnend
move.l (sp)+,d1
rts
mt_volumefineup
tst.b mt_counter
bne mt_return
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$f,d0
bra mt_volslideup
mt_volumefinedown
tst.b mt_counter
bne mt_return
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
bra mt_volslidedown2
mt_notecut
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
cmp.b mt_counter(pc),d0
bne mt_return
clr.b n_volume(a6)
move.w #0,8(a5)
rts
mt_notedelay
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
cmp.b mt_counter,d0
bne mt_return
move.w (a6),d0
beq mt_return
move.l d1,-(sp)
bra mt_doretrig
mt_patterndelay
tst.b mt_counter
bne mt_return
moveq #0,d0
move.b n_cmdlo(a6),d0
and.b #$0f,d0
tst.b mt_pattdeltime2
bne mt_return
addq.b #1,d0
move.b d0,mt_pattdeltime
rts
mt_funkit
tst.b mt_counter
bne mt_return
move.b n_cmdlo(a6),d0
and.b #$0f,d0
lsl.b #4,d0
and.b #$0f,n_glissfunk(a6)
or.b d0,n_glissfunk(a6)
tst.b d0
beq mt_return
mt_updatefunk
movem.l a0/d1,-(sp)
moveq #0,d0
move.b n_glissfunk(a6),d0
lsr.b #4,d0
beq.s mt_funkend
lea mt_funktable(pc),a0
move.b (a0,d0.w),d0
add.b d0,n_funkoffset(a6)
btst #7,n_funkoffset(a6)
beq.s mt_funkend
clr.b n_funkoffset(a6)
move.l n_loopstart(a6),d0
moveq #0,d1
move.w n_replen(a6),d1
add.l d1,d0
add.l d1,d0
move.l n_wavestart(a6),a0
addq.l #1,a0
cmp.l d0,a0
blo.s mt_funkok
move.l n_loopstart(a6),a0
mt_funkok
move.l a0,n_wavestart(a6)
moveq #-1,d0
sub.b (a0),d0
move.b d0,(a0)
mt_funkend
movem.l (sp)+,a0/d1
rts
mt_funktable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
mt_vibratotable
dc.b 0, 24, 49, 74, 97,120,141,161
dc.b 180,197,212,224,235,244,250,253
dc.b 255,253,250,244,235,224,212,197
dc.b 180,161,141,120, 97, 74, 49, 24
mt_periodtable
; tuning 0, normal
dc.w 856,808,762,720,678,640,604,570,538,508,480,453
dc.w 428,404,381,360,339,320,302,285,269,254,240,226
dc.w 214,202,190,180,170,160,151,143,135,127,120,113
; tuning 1
dc.w 850,802,757,715,674,637,601,567,535,505,477,450
dc.w 425,401,379,357,337,318,300,284,268,253,239,225
dc.w 213,201,189,179,169,159,150,142,134,126,119,113
; tuning 2
dc.w 844,796,752,709,670,632,597,563,532,502,474,447
dc.w 422,398,376,355,335,316,298,282,266,251,237,224
dc.w 211,199,188,177,167,158,149,141,133,125,118,112
; tuning 3
dc.w 838,791,746,704,665,628,592,559,528,498,470,444
dc.w 419,395,373,352,332,314,296,280,264,249,235,222
dc.w 209,198,187,176,166,157,148,140,132,125,118,111
; tuning 4
dc.w 832,785,741,699,660,623,588,555,524,495,467,441
dc.w 416,392,370,350,330,312,294,278,262,247,233,220
dc.w 208,196,185,175,165,156,147,139,131,124,117,110
; tuning 5
dc.w 826,779,736,694,655,619,584,551,520,491,463,437
dc.w 413,390,368,347,328,309,292,276,260,245,232,219
dc.w 206,195,184,174,164,155,146,138,130,123,116,109
; tuning 6
dc.w 820,774,730,689,651,614,580,547,516,487,460,434
dc.w 410,387,365,345,325,307,290,274,258,244,230,217
dc.w 205,193,183,172,163,154,145,137,129,122,115,109
; tuning 7
dc.w 814,768,725,684,646,610,575,543,513,484,457,431
dc.w 407,384,363,342,323,305,288,272,256,242,228,216
dc.w 204,192,181,171,161,152,144,136,128,121,114,108
; tuning -8
dc.w 907,856,808,762,720,678,640,604,570,538,508,480
dc.w 453,428,404,381,360,339,320,302,285,269,254,240
dc.w 226,214,202,190,180,170,160,151,143,135,127,120
; tuning -7
dc.w 900,850,802,757,715,675,636,601,567,535,505,477
dc.w 450,425,401,379,357,337,318,300,284,268,253,238
dc.w 225,212,200,189,179,169,159,150,142,134,126,119
; tuning -6
dc.w 894,844,796,752,709,670,632,597,563,532,502,474
dc.w 447,422,398,376,355,335,316,298,282,266,251,237
dc.w 223,211,199,188,177,167,158,149,141,133,125,118
; tuning -5
dc.w 887,838,791,746,704,665,628,592,559,528,498,470
dc.w 444,419,395,373,352,332,314,296,280,264,249,235
dc.w 222,209,198,187,176,166,157,148,140,132,125,118
; tuning -4
dc.w 881,832,785,741,699,660,623,588,555,524,494,467
dc.w 441,416,392,370,350,330,312,294,278,262,247,233
dc.w 220,208,196,185,175,165,156,147,139,131,123,117
; tuning -3
dc.w 875,826,779,736,694,655,619,584,551,520,491,463
dc.w 437,413,390,368,347,328,309,292,276,260,245,232
dc.w 219,206,195,184,174,164,155,146,138,130,123,116
; tuning -2
dc.w 868,820,774,730,689,651,614,580,547,516,487,460
dc.w 434,410,387,365,345,325,307,290,274,258,244,230
dc.w 217,205,193,183,172,163,154,145,137,129,122,115
; tuning -1
dc.w 862,814,768,725,684,646,610,575,543,513,484,457
dc.w 431,407,384,363,342,323,305,288,272,256,242,228
dc.w 216,203,192,181,171,161,152,144,136,128,121,114
mt_chan1temp dc.l 0,0,0,0,0,$00010000,0, 0,0,0,0
mt_chan2temp dc.l 0,0,0,0,0,$00020000,0, 0,0,0,0
mt_chan3temp dc.l 0,0,0,0,0,$00040000,0, 0,0,0,0
mt_chan4temp dc.l 0,0,0,0,0,$00080000,0, 0,0,0,0
mt_samplestarts dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
mt_songdataptr dc.l 0
mt_speed dc.b 6
mt_counter dc.b 0
mt_songpos dc.b 0
mt_pbreakpos dc.b 0
mt_posjumpflag dc.b 0
mt_pbreakflag dc.b 0
mt_lowmask dc.b 0
mt_pattdeltime dc.b 0
mt_pattdeltime2 dc.b 0
mt_enable dc.b 0
mt_patternpos dc.w 0
mt_dmacontemp dc.w 0
mt_dmadelay dc.w 800